package service

import (
	"github.com/gin-gonic/gin"
	"sensi/app/api/dto"
	"sensi/app/client/qweather"
	"sensi/app/model"
	"sensi/app/repo"
	"sensi/common/sys/database"
	"time"
)

const (
	hourFormat = "2006010215"
	dateFormat = "20060102"
)

type Service struct {
	weatherRepo *repo.Weather
	dialRepo    *repo.Dial
	deviceRepo  *repo.Device
	firmVerRepo *repo.FirmwareVersion
	qweather    *qweather.Client
}

func NewService() *Service {
	return &Service{
		weatherRepo: &repo.Weather{},
		dialRepo:    &repo.Dial{},
		deviceRepo:  &repo.Device{},
		firmVerRepo: &repo.FirmwareVersion{},
		qweather:    qweather.NewClient(),
	}
}

func (s *Service) CompositeWeather(ctx *gin.Context) (interface{}, error) {
	req := &dto.CompositeWeatherReq{}
	if err := ctx.ShouldBindJSON(req); err != nil {
		return nil, err
	}
	db := database.Instance(ctx)
	now := time.Now()
	curHour := now.Format(hourFormat)
	curDate := now.Format(dateFormat)

	hourly, err := s.weatherRepo.Hourly(db, req.City, curHour)
	if err != nil {
		return nil, err
	}
	if hourly == nil { // 没有获取过该小时的预报，调天气接口获取
		curWeather, err := s.qweather.RequestNow(ctx, req.Location)
		if err != nil {
			return nil, err
		}
		hourly = &model.WeatherHourly{
			City:     req.City,
			InHour:   curHour,
			Location: req.Location,
			Weather: &model.Weather{
				Temp:     curWeather.Temp,
				Icon:     curWeather.Icon,
				Humidity: curWeather.Humidity,
			},
		}
		if err := db.Save(hourly).Error; err != nil {
			return nil, err
		}
	}

	daily, err := s.weatherRepo.Daily(db, req.City, curDate)
	if err != nil {
		return nil, err
	}
	if daily == nil {
		foreWeather, err := s.qweather.RequestForecast(ctx, req.Location)
		if err != nil {
			return nil, err
		}
		daily = &model.WeatherDaily{
			City:     req.City,
			InDay:    curDate,
			Location: req.Location,
		}
		daily.Weather = make([]*model.WeatherForecast, 0)
		for _, item := range foreWeather {
			daily.Weather = append(daily.Weather, &model.WeatherForecast{
				FxDate:    item.FxDate,
				TempMax:   item.TempMax,
				TempMin:   item.TempMin,
				IconDay:   item.IconDay,
				IconNight: item.IconNight,
				Humidity:  item.Humidity,
			})
		}
		if err := db.Save(daily).Error; err != nil {
			return nil, err
		}
	}

	return &dto.CompositeWeatherResp{
		Current:  hourly.Weather,
		Forecast: daily.Weather,
	}, nil
}
